<?php
/**************************************************************************
 *
 *   Copyright 2010 American Public Media Group
 *
 *   This file is part of AIR2.
 *
 *   AIR2 is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   AIR2 is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with AIR2.  If not, see <http://www.gnu.org/licenses/>.
 *
 *************************************************************************/

/**
 * Organization
 *
 * A collection of AIR2 Users, for the purpose of assigning permissions
 *
 * @property integer $org_id
 * @property string $org_uuid
 * @property string $org_name
 * @property string $org_logo_uri
 * @property string $org_display_name
 * @property integer $org_parent_id
 * @property integer $org_default_prj_id
 * @property string $org_type
 * @property string $org_status
 * @property string $org_html_color
 * @property integer $org_cre_user
 * @property integer $org_upd_user
 * @property timestamp $org_cre_dtim
 * @property timestamp $org_upd_dtim
 * @property Organization $parent
 * @property Project $DefaultProject
 * @property Doctrine_Collection $OrgSysId
 * @property Doctrine_Collection $ProjectOrg
 * @property Doctrine_Collection $SrcOrg
 * @property Doctrine_Collection $SrcPrefOrg
 * @property Doctrine_Collection $UserOrg
 * @property Doctrine_Collection $children
 * @author rcavis
 * @package default
 */
class Organization extends AIR2_Record {
    /* code_master values */
    public static $STATUS_ACTIVE = 'A';
    public static $STATUS_INACTIVE = 'F';
    public static $TYPE_NEWSROOM = 'N';
    public static $TYPE_LJC = 'L';

    /* flag to trigger creation of default project */
    public static $CREATE_DEFAULT_PRJ = true;


    /**
     * Set the table columns
     */
    public function setTableDefinition() {
        $this->setTableName('organization');
        $this->hasColumn('org_id', 'integer', 4, array(
                'primary' => true,
                'autoincrement' => true,
            ));
        $this->hasColumn('org_uuid', 'string', 12, array(
                'fixed' => true,
                'notnull' => true,
                'unique' => true,
            ));
        $this->hasColumn('org_name', 'string', 32, array(
                'notnull' => true,
                'unique' => true,
            ));
        $this->hasColumn('org_logo_uri', 'string', 255, array(

            ));
        $this->hasColumn('org_display_name', 'string', 128, array(

            ));
        $this->hasColumn('org_parent_id', 'integer', 4, array(

            ));
        $this->hasColumn('org_default_prj_id', 'integer', 4, array(
                'notnull' => true,
                'default' => 1, //system default project (see fixtures)
            ));
        $this->hasColumn('org_type', 'string', 1, array(
                'fixed' => true,
                'notnull' => true,
                'default' => self::$TYPE_NEWSROOM,
            ));
        $this->hasColumn('org_status', 'string', 1, array(
                'fixed' => true,
                'notnull' => true,
                'default' => self::$STATUS_ACTIVE,
            ));
        $this->hasColumn('org_html_color', 'string', 6, array(
                'fixed' => true,
                'default' => '000000',
                'notnull' => true,
            ));
        $this->hasColumn('org_cre_user', 'integer', 4, array(
                'notnull' => true,
            ));
        $this->hasColumn('org_upd_user', 'integer', 4, array(

            ));
        $this->hasColumn('org_cre_dtim', 'timestamp', null, array(
                'notnull' => true,
            ));
        $this->hasColumn('org_upd_dtim', 'timestamp', null, array(

            ));

        parent::setTableDefinition();
    }


    /**
     * Set table relations
     */
    public function setUp() {
        parent::setUp();
        $this->hasMany('OrgSysId', array(
                'local' => 'org_id',
                'foreign' => 'osid_org_id'
            ));
        $this->hasMany('ProjectOrg', array(
                'local' => 'org_id',
                'foreign' => 'porg_org_id',
            ));
        $this->hasMany('SrcOrg', array(
                'local' => 'org_id',
                'foreign' => 'so_org_id'
            ));
        $this->hasMany('SrcPrefOrg', array(
                'local' => 'org_id',
                'foreign' => 'spo_org_id'
            ));
        $this->hasMany('UserOrg', array(
                'local' => 'org_id',
                'foreign' => 'uo_org_id'
            ));
        $this->hasOne('Project as DefaultProject', array(
                'local' => 'org_default_prj_id',
                'foreign' => 'prj_id'
            ));
        // add sub-orgs and parent orgs
        $this->hasOne('Organization as parent', array(
                'local' => 'org_parent_id',
                'foreign' => 'org_id',
                'onDelete' => 'CASCADE',
            ));
        $this->hasMany('Organization as children', array(
                'local' => 'org_id',
                'foreign' => 'org_parent_id'
            ));
    }


    /**
     * Make sure new Organizations get default projects
     *
     * @param Doctrine_Event $event
     */
    public function postInsert($event) {
        if (self::$CREATE_DEFAULT_PRJ && $this->org_default_prj_id == 1 && $this->org_type != 'T') {
            $p = new Project();
            $p->prj_name = air2_urlify($this->org_name);
            $p->prj_display_name = 'Project '.$this->org_display_name;
            $p->prj_desc = 'Default project for organization "'.$this->org_display_name.'"';
            $p->ProjectOrg[0]->porg_org_id = $this->org_id;
            $p->ProjectOrg[0]->porg_contact_user_id = $this->org_cre_user;

            // make sure prj_name is unique
            $count = 0;
            $orig = $p->prj_name;
            $tbl = Doctrine::getTable('Project');
            $name = $tbl->findOneBy('prj_name', $p->prj_name);
            while ($name) {
                $p->prj_name = $orig.'_'.$count;
                $name = $tbl->findOneBy('prj_name', $p->prj_name);
            }

            // save, and make default
            $p->save();
            $this->org_default_prj_id = $p->prj_id;
            $this->save();
        }
        parent::postInsert($event);
    }


    /**
     * Add custom search query (from the get param 'q')
     *
     * @param AIR2_Query $q
     * @param string  $alias
     * @param string  $search
     * @param boolean $useOr
     */
    public static function add_search_str(&$q, $alias, $search, $useOr=null) {
        $a = ($alias) ? "$alias." : "";
        $str = "(".$a."org_name LIKE ? OR ".$a."org_display_name LIKE ?)";
        if ($useOr) {
            $q->orWhere($str, array("%$search%", "$search%"));
        }
        else {
            $q->addWhere($str, array("%$search%", "$search%"));
        }
    }


    /**
     *
     *
     * @param array   $users
     * @param unknown $role  (optional)
     */
    public function add_users(array $users, $role=2) {
        foreach ($users as $user) {
            $uo = new UserOrg();
            $uo->uo_user_id     = $user->user_id;
            $uo->uo_ar_id       = $role;
            $uo->uo_org_id      = $this->org_id;
            $uo->uo_home_flag   = false;
            $uo->uo_status      = self::$STATUS_ACTIVE;
            $uo->uo_notify_flag = true;
            $this->UserOrg[] = $uo;
        }
    }



    /**
     *
     *
     * @return array $active_parent_org_ids
     */
    public function get_active_parents_ids() {
        $pids = array();
        if ($this->org_status != self::$STATUS_ACTIVE) {
            return $pids;
        }
        $parent = $this->parent;
        while ( $parent && $parent->org_id && $parent->org_status == self::$STATUS_ACTIVE) {
            if ($parent->org_id === $parent->org_parent_id) {
                break;
            }
            $pids[] = $parent->org_id;
            $parent = $parent->parent;
        }
        return $pids;
    }


    /**
     *
     *
     * @param User    $user
     * @return authz integer
     */
    public function user_may_read($user) {
        if ($user->is_system()) {
            return AIR2_AUTHZ_IS_SYSTEM;
        }
        return AIR2_AUTHZ_IS_PUBLIC;
    }


    /**
     *
     *
     * @param User    $user
     * @return authz integer
     */
    public function user_may_write($user) {
        if ($user->is_system()) {
            return AIR2_AUTHZ_IS_SYSTEM;
        }

        // may edit this org or create child if a MANAGER
        $authz = $user->get_authz();
        foreach ($authz as $org_id => $role) {
            if ($org_id == $this->org_id && $role & AIR2_AUTHZ_MANAGER) {
                return AIR2_AUTHZ_IS_MANAGER;
            }
            if (!$this->org_id
                && isset($this->org_parent_id)
                && $this->org_parent_id == $org_id
                && $role & AIR2_AUTHZ_MANAGER
            ) {
                return AIR2_AUTHZ_IS_MANAGER;
            }
        }

        return AIR2_AUTHZ_IS_DENIED;
    }


    /**
     *
     *
     * @param User    $user
     * @return authz integer
     */
    public function user_may_manage($user) {
        return $this->user_may_write($user);
    }


}
